package com.xy.core.constant;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@Slf4j
public class Rog {
    //日志文件
    private String logName;

    /**
     * 构造函数
     *
     * @param logName
     */
    public Rog(String logName) {
        this.logName = logName;
    }


    /**
     * Log a message at the ERROR level.
     *
     * @param msg the message string to be logged
     */
    public void error(String msg) {
        log.error(msg);
        append(this.logName, msg);
    }

    /**
     * Log a message at the ERROR level.
     *
     * @param msg the message string to be logged
     */
    public void error(String msg, Throwable ex) {
        log.error(msg, ex);
        append(this.logName, msg);
    }


    /**
     * Log a message at the INFO level.
     *
     * @param msg the message string to be logged
     */
    public void info(String msg) {
        log.info(msg);
        append(this.logName, msg);
    }

    /**
     * Log a message at the DEBUG level.
     *
     * @param msg the message string to be logged
     */
    public void debug(String msg) {
        log.debug(msg);
        append(this.logName, msg);
    }

    /**
     * Log a message at the DEBUG level.
     *
     * @param msgs the message string to be logged
     */
    public void log(String... msgs) {
        append(this.logName, msgs);
    }

    //执行线程
    private static Map<String, ExecutorService> logEsMap = new HashMap<>();
    //文件名称
    private static Map<String, Map<String, FileWriter>> writeLogMap = new HashMap<>();

    /**
     * 取得执行池
     *
     * @param logName
     * @return
     */
    private static synchronized ExecutorService getEs(String logName) {
        ExecutorService es = logEsMap.get(logName);
        if (es == null || es.isShutdown() || es.isTerminated()) {
            es = Executors.newSingleThreadExecutor();
            logEsMap.put(logName, es);
        }
        return es;
    }

    /**
     * 取得名称
     *
     * @param logName
     * @return
     */
    private static synchronized FileWriter getWriter(String logName) {
        //日期
        String nowDate = DateUtil.format(new Date(), "yyyyMMdd");
        //不包含，就是新的一天，清理掉旧的数据
        if (!writeLogMap.containsKey(nowDate)) {
            for (Map<String, FileWriter> writeMap : writeLogMap.values()) {
                for (FileWriter w : writeMap.values()) {
                    try {
                        w.close();
                    } catch (Exception ex) {
                    }
                }
            }
            writeLogMap.clear();
            //添加新的
            writeLogMap.put(nowDate, new HashMap<>());
        }
        try {
            Map<String, FileWriter> logMap = writeLogMap.get(nowDate);
            if (logMap == null) {
                logMap = new HashMap<>();
            }
            FileWriter w = logMap.get(logName);
            if (w == null) {
                File file = new File("/home/lock/self/" + nowDate + "/" + logName + ".lock");
                if (!file.exists()) {
                    file.getParentFile().mkdirs();
                    file.createNewFile();
                }
                // 使用FileWriter构造函数创建文件输出流
                w = new FileWriter(file, true);
                logMap.put(logName, w);

            }
            return w;
        } catch (Exception ex) {
            log.error("创建自定义日志文件异常：" + ex.getMessage(), ex);
            return null;
        }

    }

    /**
     * 添加日志
     *
     * @param logName
     * @param contentList
     */
    private static void append(final String logName, final String... contentList) {
        if (logName == null || logName.length() == 0) {
            return;
        }
        if (contentList == null || contentList.length == 0) {
            return;
        }
        //取得线程池
        ExecutorService es = getEs(logName);
        //提交，包装顺序执行
        es.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    FileWriter w = getWriter(logName);
                    if (w != null) {
                        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String date = f.format(new Date());
                        StringBuilder sb = new StringBuilder();
                        for (String content : contentList) {
                            sb.append(date).append("    ").append(content).append("\r\n");
                        }
                        w.write(sb.toString());
                        w.flush();
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    }


}
